<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  
  <meta name="generator" content="Hugo 0.98.0" />

  
  <meta name="description" content="走在通往幸福的路上">
  

  
  <link rel="apple-touch-icon" sizes="180x180" href="https://blog.v5u.win/apple-touch-icon.png">

  
  <link rel="icon" type="image/png" sizes="32x32" href="https://blog.v5u.win/favicon-32x32.png">

  
  <link rel="icon" type="image/png" sizes="16x16" href="https://blog.v5u.win/favicon-16x16.png">

  
  <link rel="manifest" href="https://blog.v5u.win/site.webmanifest">

  
  <link rel="mask-icon" href="https://blog.v5u.win/safari-pinned-tab.svg" color="">

  <meta name="msapplication-TileColor" content="">

  <meta name="theme-color" content="">

  
  <link rel="stylesheet" href="https://blog.v5u.win/css/bootstrap.min.css" />

  
  <title>React学习 | 为吾优</title>
  

  <style>
body {
  min-width: 300px;
}

.custom-navbar {
  margin-bottom: 1em;
  height: 60px;
}

.custom-navbar a {
  display: inline-block; 
  padding: 18px 0;
  margin-right: 1em; 
  font-weight: bold; 
}

.custom-navbar a:hover,
.custom-navbar a:focus {
  text-decoration: none; 
}

@media print {
  .custom-navbar {
    display: none;
  }
}

article {
  padding-bottom: 1em;
}

img {
  max-width: 100%;
}


body {
  background-color: #fff;
}



body {
  color: #212529;
}



a {
  color: #007bff;
}



a:hover,
a:focus {
  color: #0056b3;
}



.custom-navbar {
  background-color: #212529;
}



.custom-navbar a {
  color: rgba(255,255,255,.75);
}



.custom-navbar a:hover,
.custom-navbar a:focus {
  color: rgba(255,255,255,1);
}



.container {
  max-width: 800px;
}





</style>
</head>

<body>
  <nav class="custom-navbar">
  <div class="container">
    
    <a href="/">文章</a>
    
    <a href="/tags/">标签</a>
    
    <a href="/about/">关于</a>
    
    <a href="/index.xml">RSS</a>
    
  </div>
</nav>
  
  <div class="container">
    <article>
      <h1>React学习</h1>
<p>React学习</p>
<h2 id="两个重要的概念虚拟domdiff算法">两个重要的概念：虚拟DOM，diff算法</h2>
<p>虚拟DOM：用js对象模拟HTML的DOM树，为了方便比较，减少渲染</p>
<p>diff算法由3种组成：</p>
<p>tree diff DOM树按层对比</p>
<p>component diff 在每层里按组件对比</p>
<p>element diff：在每个组件中 按元素进行对比</p>
<h2 id="工程启动流程">工程启动流程：</h2>
<p>创建webpack：npm init -y 创建dist 和 src文件夹，创建文件src/index.html src/main.js</p>
<p>安装webpack：<code>npm -i webpack -D</code></p>
<p><code>yarn add web-dev-server --dev</code> 自动编译js</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span>  <span style="color:#e6db74">&#34;scripts&#34;</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;test&#34;</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;echo \&#34;Error: no test specified\&#34; &amp;&amp; exit 1&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;dev&#34;</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;webpack-dev-server --port 8080 --hot --host&#34;</span><span style="color:#75715e">// 最佳实践
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>  },
</span></span></code></pre></div><p>html-webpack-plugin 将页面生成到内存中去</p>
<p>webpack.config.js文件中的配置</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#75715e">// 向外暴露一个打包的对象
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">module</span>.<span style="color:#a6e22e">exports</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">mode</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;development&#39;</span>,<span style="color:#75715e">// production develoment 设置压缩文件的方式
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#75715e">// webpack 4.0 中约定大于配置，默认 src/index.js 是入口文件
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><hr>
<p><strong>react</strong> 专门用来创建组件和虚拟DOM，同时组件的生命周期都在这个包里</p>
<p><strong>react-dom</strong> 专门进行DOM操作，最主要的应用场景，就是ReactDOM.rander()</p>
<p>实例代码：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#75715e">// 1. 导入
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 2. 创建虚拟DOM元素
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 3. 使用ReactDOM把虚拟DOM渲染到屏幕上
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 导入react的别名必须这么写
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">import</span>  <span style="color:#a6e22e">React</span>  <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;react&#39;</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">import</span>  <span style="color:#a6e22e">ReactDOM</span>  <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#34;react-dom&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 参数1 创建的元素的类型，字符串，表示元素名称
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 参数2 一个对象或者null，表示这个DOM的属性
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 参数3 子节点 包括其他虚拟DOM获取文本子节点
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 参数n 其他子节点
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// &lt;h1 id=&#34;myh&#34; title=&#34;这是一个h1&#34;&gt;这是一个没有感情的h1&lt;/h1&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">myh1</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">React</span>.<span style="color:#a6e22e">createElement</span>(<span style="color:#e6db74">&#39;h1&#39;</span>, {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">id</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;myh1&#39;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">title</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;这是一个h1&#39;</span>
</span></span><span style="display:flex;"><span>}, <span style="color:#e6db74">&#34;这是一个没有感情的h1&#34;</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">mdiv</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">React</span>.<span style="color:#a6e22e">createElement</span>(<span style="color:#e6db74">&#39;div&#39;</span>,<span style="color:#66d9ef">null</span>,<span style="color:#e6db74">&#39;这是一个div&#39;</span>,<span style="color:#a6e22e">myh1</span>)
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 参数1 目标虚拟DOM
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 参数2 指定页面的容器,一个DOM元素
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">ReactDOM</span>.<span style="color:#a6e22e">render</span>(<span style="color:#a6e22e">mdiv</span>, document.<span style="color:#a6e22e">getElementById</span>(<span style="color:#e6db74">&#39;app&#39;</span>))
</span></span></code></pre></div><h3 id="jsx--js--xml">JSX = js + xml</h3>
<p>JSX 语法本质是通过babel转换成 React.createElement()形式</p>
<p>依赖包：babel-core babel-loader babel-plugin-transform-runtime &ndash;dev</p>
<p>关于语法解析的：babel-preset-env babel-preset-stage-0 babel-preset-react &ndash;dev</p>
<p>@babel/core、@babel/preset-env、@babel/runtime、@babel/plugin-transform-runtime、@babel/plugin-proposal-class-properties、@babel/preset-react这几个包安装一下，然后在.babelrc文件中添加{&ldquo;presets&rdquo;:[&quot;@babel/preset-env&quot;,&quot;@babel/preset-react&quot;], &ldquo;plugins&rdquo;:[&quot;@babel/transform-runtime&quot;,&quot;@babel/plugin-proposal-class-properties&quot;]}</p>
<p>注：react中需要把key添加给被 foreach 或map 或 for循环直接没控制的那些元素（也就是最外层的元素）</p>
<p>jsx 注释：jsx的{}中可以写任何合法的js代码，包括注释</p>
<pre tabindex="0"><code>{/* 注释单行 */}
{
// 注释多行
}
</code></pre><p>为jsx添加类名，需要用className代替class；htmlFor代替label的for属性</p>
<h3 id="组件创建和使用">组件创建和使用</h3>
<p>为组件传递数据</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-jsx" data-lang="jsx"><span style="display:flex;"><span><span style="color:#75715e">// 第一种创建组件方式，组件名称首字母必须大写
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">Hello</span>(<span style="color:#a6e22e">props</span>) {<span style="color:#75715e">// 在Props 上获取dog对象
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// react 和Vue 中的 props 对象所有属性都是 只读 read only的
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#a6e22e">props</span>.<span style="color:#a6e22e">name</span>);
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 返回一个 虚拟DOM
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">div</span>&gt;<span style="color:#a6e22e">这是Hello组件</span> <span style="color:#f92672">--</span> {<span style="color:#a6e22e">props</span>.<span style="color:#a6e22e">name</span>}<span style="color:#f92672">--</span> {<span style="color:#a6e22e">props</span>.<span style="color:#a6e22e">age</span>} <span style="color:#f92672">--</span> {<span style="color:#a6e22e">props</span>.<span style="color:#a6e22e">gander</span>}&lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>{<span style="color:#75715e">/* 直接将组件名称以标签的形式，丢到页面上 */</span>}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">Hello</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">name</span>} <span style="color:#a6e22e">age</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">age</span>} <span style="color:#a6e22e">gander</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">gander</span>}&gt;&lt;/<span style="color:#f92672">Hello</span>&gt;
</span></span></code></pre></div><p>react chrome开发插件 react developer tools</p>
<p><strong>注：组件名称首字母必须大写</strong></p>
<p>默认不做单独的配置的话，不能省略后缀名
可以配置webpack.config.js 省略后缀名</p>
<p>@代表src目录 配置webpack的alias 字段</p>
<pre tabindex="0"><code>import Hello from &#39;@/components/Hello&#39;
</code></pre><h3 id="class-属性">class 属性</h3>
<p>this.props 只读</p>
<p>this.state 可读可写</p>
<p>class 有私有属性state 和生命周期</p>
<h3 id="jsx-style-样式">JSX style 样式</h3>
<p>{<em>/* jsx中的样式写法{{color: &lsquo;red&rsquo;}} */</em>}</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#a6e22e">css文件</span>
</span></span><span style="display:flex;"><span>.<span style="color:#a6e22e">title</span>{
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">color</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">red</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#f92672">-----</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">webpack</span> <span style="color:#a6e22e">配置</span> <span style="color:#a6e22e">解析css</span> <span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">依赖包</span> <span style="color:#a6e22e">style</span><span style="color:#f92672">-</span><span style="color:#a6e22e">loader</span> <span style="color:#a6e22e">css</span><span style="color:#f92672">-</span><span style="color:#a6e22e">loader</span>
</span></span><span style="display:flex;"><span>{<span style="color:#a6e22e">test</span><span style="color:#f92672">:</span> <span style="color:#e6db74">/\.css$/</span>,<span style="color:#a6e22e">use</span><span style="color:#f92672">:</span> [<span style="color:#e6db74">&#39;style-loader&#39;</span>,<span style="color:#e6db74">&#39;css-loader?modules&#39;</span>]}<span style="color:#75715e">// 打包处理css样式表，从右向左 处理，css处理完交给style处理 
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>            <span style="color:#75715e">// style-loader loader不嫩省略，webpack 1.0 用的是 style，后边都加-loader了，搜blog不要被误导
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">自定义</span> <span style="color:#a6e22e">样式对象的名称</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">css</span><span style="color:#f92672">-</span><span style="color:#a6e22e">loader</span><span style="color:#f92672">?</span><span style="color:#a6e22e">modules</span><span style="color:#f92672">&amp;</span><span style="color:#a6e22e">localIdentName</span><span style="color:#f92672">=</span>[<span style="color:#a6e22e">path</span>][<span style="color:#a6e22e">name</span>]<span style="color:#f92672">-</span>[<span style="color:#a6e22e">local</span>]<span style="color:#f92672">-</span>[<span style="color:#a6e22e">hash</span><span style="color:#f92672">:</span><span style="color:#ae81ff">3</span>]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">path</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">-</span><span style="color:#a6e22e">css</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">name</span> <span style="color:#a6e22e">文件name</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">local</span> <span style="color:#a6e22e">css中的样式名称</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">hash</span> <span style="color:#a6e22e">默认全length</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">-----</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">使用</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">import</span> <span style="color:#a6e22e">cssObj</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#34;@/css/cssList.css&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">h1</span> <span style="color:#a6e22e">className</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;title&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">这是评论列表组件</span><span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/h1&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">cssObj是全局的</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">整个项目都生效</span>
</span></span></code></pre></div><p>解决样式冲突：vue <code>&lt;style scoped&gt;</code></p>
<p>css 模块化只针对 class和id 不作用于标签</p>
<p>:global 全局，不模块化</p>
<p>自己的样式用scss结尾</p>
<p>第三方的用css结尾，这样就区分了个人和其他</p>
<p><code>sass-loader node-sass</code></p>
<h3 id="绑定事件">绑定事件</h3>
<p>最佳实践</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">button</span> <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{()=&gt;{<span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">myClickHandler</span>()}}<span style="color:#f92672">&gt;</span><span style="color:#a6e22e">按钮</span><span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/button&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">myClickHandler</span> <span style="color:#f92672">=</span> ()=&gt;{        <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;点击事件&#39;</span>);       }
</span></span></code></pre></div><p>箭头函数本身是一个匿名函数，和匿名函数不同的是会改变this指针的指向，它会根据环境选择箭头外部的那个对象。</p>
<p>修改数据使用this.setState({msg:&lsquo;改&rsquo;}), 是异步执行的</p>
<h3 id="jsx注释折叠">JSX注释折叠</h3>
<pre tabindex="0"><code>//#region
// 我是JSX注释
//#endregion
</code></pre><h3 id="实现双向数据绑定"><em>实现双向数据绑定</em></h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-jsx" data-lang="jsx"><span style="display:flex;"><span> &lt;<span style="color:#f92672">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span>{<span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">state</span>.<span style="color:#a6e22e">msg</span>} <span style="color:#a6e22e">onChange</span><span style="color:#f92672">=</span> {(<span style="color:#a6e22e">e</span>)=&gt;<span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">txtChanged</span>(<span style="color:#a6e22e">e</span>)} /&gt;
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">txtChanged</span> <span style="color:#f92672">=</span> (<span style="color:#a6e22e">e</span>)=&gt;{
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// console.log(this.refs.txt.value);
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">// console.log(e.target.value);
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//  实现双向数据绑定
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">newValue</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">e</span>.<span style="color:#a6e22e">target</span>.<span style="color:#a6e22e">value</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">setState</span>({
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">msg</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">newValue</span>
</span></span><span style="display:flex;"><span>        })
</span></span><span style="display:flex;"><span>    }
</span></span></code></pre></div><h2 id="第三方库使用-ant">第三方库使用 ant</h2>
<p>插件 react-app-rewired 替换 react-scripts 实现按需加载css</p>
<p>babel-plugin-import</p>

    </article>
  </div>

  
  
  

  
</body>

</html>